GLuint buffer_id;
GLuint position_id;
GLuint uv_id;
+ GskQuadVertex *quads;
+ int n_quads;
+ gboolean in_use : 1;
} Vao;
typedef struct {
{
Vao *v = data;
+ g_free (v->quads);
glDeleteBuffers (1, &v->buffer_id);
glDeleteVertexArrays (1, &v->vao_id);
g_slice_free (Vao, v);
driver->in_frame = FALSE;
}
-void
+int
gsk_gl_driver_collect_textures (GskGLDriver *driver)
{
GHashTableIter iter;
gpointer value_p = NULL;
+ int old_size;
- g_return_if_fail (GSK_IS_GL_DRIVER (driver));
- g_return_if_fail (!driver->in_frame);
+ g_return_val_if_fail (GSK_IS_GL_DRIVER (driver), 0);
+ g_return_val_if_fail (!driver->in_frame, 0);
+
+ old_size = g_hash_table_size (driver->textures);
g_hash_table_iter_init (&iter, driver->textures);
while (g_hash_table_iter_next (&iter, NULL, &value_p))
Texture *t = value_p;
if (t->in_use)
- t->in_use = FALSE;
+ {
+ t->in_use = FALSE;
+ g_clear_pointer (&t->fbos, g_array_unref);
+ }
else
g_hash_table_iter_remove (&iter);
}
+
+ return old_size - g_hash_table_size (driver->textures);
+}
+
+int
+gsk_gl_driver_collect_vaos (GskGLDriver *driver)
+{
+ GHashTableIter iter;
+ gpointer value_p = NULL;
+ int old_size;
+
+ g_return_val_if_fail (GSK_IS_GL_DRIVER (driver), 0);
+ g_return_val_if_fail (!driver->in_frame, 0);
+
+ old_size = g_hash_table_size (driver->vaos);
+
+ g_hash_table_iter_init (&iter, driver->vaos);
+ while (g_hash_table_iter_next (&iter, NULL, &value_p))
+ {
+ Vao *v = value_p;
+
+ if (v->in_use)
+ v->in_use = FALSE;
+ else
+ g_hash_table_iter_remove (&iter);
+ }
+
+ return old_size - g_hash_table_size (driver->vaos);
}
static Texture *
t = find_texture_by_size (driver->textures, width, height);
if (t != NULL && !t->in_use)
{
+ GSK_NOTE (OPENGL, g_print ("Reusing Texture(%d) for size %dx%d\n",
+ t->texture_id, t->width, t->height));
t->in_use = TRUE;
return t->texture_id;
}
return t->texture_id;
}
+static Vao *
+find_vao (GHashTable *vaos,
+ int position_id,
+ int uv_id,
+ int n_quads,
+ GskQuadVertex *quads)
+{
+ GHashTableIter iter;
+ gpointer value_p = NULL;
+
+ g_hash_table_iter_init (&iter, vaos);
+ while (g_hash_table_iter_next (&iter, NULL, &value_p))
+ {
+ Vao *v = value_p;
+
+ if (v->position_id != position_id || v->uv_id != uv_id)
+ continue;
+
+ if (v->n_quads != n_quads)
+ continue;
+
+ if (memcmp (v->quads, quads, sizeof (GskQuadVertex) * n_quads) == 0)
+ return v;
+ }
+
+ return NULL;
+}
+
int
gsk_gl_driver_create_vao_for_quad (GskGLDriver *driver,
int position_id,
g_return_val_if_fail (GSK_IS_GL_DRIVER (driver), -1);
g_return_val_if_fail (driver->in_frame, -1);
+ v = find_vao (driver->vaos, position_id, uv_id, n_quads, quads);
+ if (v != NULL && !v->in_use)
+ {
+ GSK_NOTE (OPENGL, g_print ("Reusing VAO(%d)\n", v->vao_id));
+ v->in_use = TRUE;
+ return v->vao_id;
+ }
+
glGenVertexArrays (1, &vao_id);
glBindVertexArray (vao_id);
v->buffer_id = buffer_id;
v->position_id = position_id;
v->uv_id = uv_id;
+ v->n_quads = n_quads;
+ v->quads = g_memdup (quads, sizeof (GskQuadVertex) * n_quads);
+ v->in_use = TRUE;
g_hash_table_insert (driver->vaos, GINT_TO_POINTER (vao_id), v);
#ifdef G_ENABLE_DEBUG
return TRUE;
}
-static void
-render_item_clear (RenderItem *item,
- GskGLRenderer *self)
-{
- gsk_gl_driver_destroy_vao (self->gl_driver, item->render_data.vao_id);
-}
-
static void
gsk_gl_renderer_clear_tree (GskGLRenderer *self)
{
- int i;
+ int removed_textures, removed_vaos;
if (self->gl_context == NULL)
return;
gdk_gl_context_make_current (self->gl_context);
- for (i = 0; i < self->render_items->len; i++)
- {
- RenderItem *item = &g_array_index (self->render_items, RenderItem, i);
-
- render_item_clear (item, self);
- }
-
g_clear_pointer (&self->render_items, g_array_unref);
- gsk_gl_driver_collect_textures (self->gl_driver);
+ removed_textures = gsk_gl_driver_collect_textures (self->gl_driver);
+ removed_vaos = gsk_gl_driver_collect_vaos (self->gl_driver);
+
+ GSK_NOTE (OPENGL, g_print ("Collected: %d textures, %d vaos\n",
+ removed_textures,
+ removed_vaos));
}
static void